package com.wmyg.scanninggun.async;

import com.wmyg.antifake.enums.DataPrepareState;
import com.wmyg.scanninggun.bean.Bill;
import com.wmyg.scanninggun.bean.DataPre;
import com.wmyg.scanninggun.dao.BillMapper;
import com.wmyg.scanninggun.dao.DataPreMapper;
import com.wmyg.scanninggun.dao.FabricDao;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component
public class PackageAsync {

    @Autowired
    DataPreMapper dataPreMapper;

    @Autowired
    BillMapper billMapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    FabricDao fabricDao;

    @Async(value = "asyncBillInsert")
    @Transactional(rollbackFor = RuntimeException.class)
    public void insertBilltoFabric(Bill bill) {
        while (true) {
            try {
                fabricDao.uploadBill(bill);
                break;
            } catch (Throwable throwable) {
                log.error("Upload failed, reuploading...");
                log.error("cause by:" + throwable.getMessage());
                continue;
            }
        }
        billMapper.uploaded(bill);
    }

    @Async(value = "asyncDataPrepare")
    @Transactional(rollbackFor = Throwable.class)
    public void dataPrepareThread(String batchKey, List<String> batchKeys) {
        log.info("The data prepare thread is starting");
        redisTemplate.opsForValue().set(batchKey.substring(0,32), DataPrepareState.PREPARING);
        try {
            for (String b :
                    batchKeys) {
                log.info("Begin to search for {}", b);
                List<String> keys = fabricDao.getPreData(b);
                for (String key :
                        keys) {
                    List<String> qrCodes = fabricDao.getPreDataForEach(key);
                    for (String qrCode :
                            qrCodes) {
                        DataPre dataPre = new DataPre();
                        dataPre.setQrCode(qrCode);
                        dataPre.setBatch(batchKey.substring(0,32));
                        dataPreMapper.insert(dataPre);
                    }
                    ArrayList<DataPre> dataPres = new ArrayList<>();
                    for (String qrCode :
                            qrCodes) {
                        DataPre dataPre = new DataPre();
                        dataPre.setQrCode(qrCode);
                        dataPre.setBatch(batchKey.substring(0,32));
                        dataPres.add(dataPre);
                    }
                }
            }

            redisTemplate.opsForValue().set(batchKey.substring(0,32), DataPrepareState.COMPLETE);
        } catch (Throwable throwable) {
            redisTemplate.opsForValue().set(batchKey.substring(0,32), DataPrepareState.FAILED);
            throwable.printStackTrace();
        }
    }

}
